
#include <iostream>

#include <windows.h>

#include "SDL.h"

#include "common.h"
#include "WGLBitmapFont.h"
#include "LogUtil.h"

using namespace std;

__BEGIN_NAMESPACE_DECL_

WGLBitmapFont::WGLBitmapFont()
    : listBase_(0)
{
}

// Based on the glXUseXFont() example code at the OpenGL
// fontsurvey site:
//   http://www.opengl.org/resources/features/fontsurvey/
bool
WGLBitmapFont::LoadFont (const char *fontname)
{
    HFONT font, oldfont;
    HDC hDC;       // drawing context

    // Generate 256 consecutive display lists
    listBase_ = glGenLists(256);
    if (!glIsList(listBase_)) {
        ERROR << "Unable to allocate enough display lists." << endl;
        return false;
    }

    // Based on NeHe tutorial 13.
    // Use CreateFont to create/load the font.
    font = CreateFont(-18,                  // Height
                      0,                    // Width
                      0,                    // Angle of Escapement
                      0,                    // Orientation Angle
                      FW_BOLD,              // Font Weight
                      FALSE,                // Italic
                      FALSE,                // Underline
                      FALSE,                // Strikeout
                      ANSI_CHARSET,         // Character set
                      OUT_TT_PRECIS,        // Output Precision
                      CLIP_DEFAULT_PRECIS,  // Clipping Precision
                      ANTIALIASED_QUALITY,  // Output Quality
                      FF_DONTCARE|DEFAULT_PITCH,   // Family and Pitch
                      fontname);

    glPushAttrib(GL_LIST_BIT | GL_ENABLE_BIT | GL_CURRENT_BIT);
    glColor3f (1.0,1.0,1.0);
    glDisable (GL_TEXTURE_2D);
    glDisable (GL_LIGHTING);

    hDC = wglGetCurrentDC();
    oldfont = (HFONT)SelectObject (hDC, font);
    wglUseFontBitmaps (hDC, 0, 256, listBase_);
    SelectObject (hDC, oldfont);
    DeleteObject (font);

    glPopAttrib();

    return true;
}

int
WGLBitmapFont::Print(const char *fmt, ...) const
{
    va_list args;
    char msg[512];
    int retval;

    if (!glIsList(listBase_)) {
        ERROR << "Bad display list" << endl;
        return 0;
    }

    va_start(args, fmt);
    retval = vsnprintf (msg, 512, fmt, args);
    va_end(args);

    glPushAttrib(GL_LIST_BIT | GL_ENABLE_BIT | GL_CURRENT_BIT);
    glColor3f (1.0,1.0,1.0);
    glDisable (GL_TEXTURE_2D);
    glDisable (GL_LIGHTING);
    glDisable (GL_DEPTH_TEST);
    glListBase(listBase_);
    glCallLists(strlen(msg), GL_UNSIGNED_BYTE, (GLubyte *)msg);
    glPopAttrib();

    return retval;
}


WGLBitmapFont::~WGLBitmapFont()
{
    if (listBase_)
        glDeleteLists(listBase_, 256);
}

__END_NAMESPACE_DECL_
